﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace ICTCLAS
{
    //字符编码类型定义
    public enum eCodeType
    {
        CODE_TYPE_UNKNOWN,//type unknown
        CODE_TYPE_ASCII,//ASCII
        CODE_TYPE_GB,//GB2312,GBK,GB10380
        CODE_TYPE_UTF8,//UTF-8
        CODE_TYPE_BIG5//BIG5
    }
    [StructLayout(LayoutKind.Explicit)]
    //处理结果类型定义
    public struct result_t
    {
        [FieldOffset(0)]
        public int start;
        [FieldOffset(4)]
        public int length;
        [FieldOffset(8)]
        public int sPos;
        [FieldOffset(12)]
        public int sPosLow;
        [FieldOffset(16)]
        public int POS_id;
        [FieldOffset(20)]
        public int word_ID;
        [FieldOffset(24)]
        public int word_type;
        [FieldOffset(28)]
        public int weight;

    }

    public class WordSegmentResultItem
    {
        public string Word { get; set; }
        public int Type { get; set; }
        public string POS { get; set; }

        public override string ToString()
        {
            return Word + " /" + POS;
        }
    }

    /// <summary>
    /// Class1 的摘要说明。
    /// </summary>
    public static class WordSegment
    {
        const string path = @"WordSegment\ICTCLAS50.dll";

        [DllImport(path, CharSet = CharSet.Ansi, EntryPoint = "ICTCLAS_Init")]
        private static extern bool ICTCLAS_Init(String sInitDirPath);

        [DllImport(path, CharSet = CharSet.Ansi, EntryPoint = "ICTCLAS_Exit")]
        private static extern bool ICTCLAS_Exit();

        [DllImport(path, CharSet = CharSet.Ansi, EntryPoint = "ICTCLAS_ParagraphProcessAW")]
        private static extern int ICTCLAS_ParagraphProcessAW(String sParagraph, [Out, MarshalAs(UnmanagedType.LPArray)]result_t[] result, eCodeType eCT, int bPOSTagged);

        [DllImport(path, CharSet = CharSet.Ansi, EntryPoint = "ICTCLAS_ParagraphProcess")]
        private static extern int ICTCLAS_ParagraphProcess(String sParagraph, int nPaLen, String sResult, eCodeType eCt, int bPOStagged);

        [DllImport(path, CharSet = CharSet.Ansi, EntryPoint = "ICTCLAS_ImportUserDictFile")]
        private static extern int ICTCLAS_ImportUserDictFile(String sFilename, eCodeType eCT);

        [DllImport(path, CharSet = CharSet.Ansi, EntryPoint = "ICTCLAS_SaveTheUsrDic")]
        private static extern bool ICTCLAS_SaveTheUsrDic();

        public static string GetPOSString(int nPOS)
        {
            string sPOSRet;

            if (nPOS > 256 * 25600)
            {
                sPOSRet = "?";
            }
            else if (nPOS > Convert.ToInt32('a') * 25600)
            {
                if ((nPOS / 100) % 256 != 0)
                    sPOSRet = string.Format("{0}{1}+{2}", Convert.ToChar(nPOS / 25600), Convert.ToChar((nPOS / 100) % 256), nPOS % 100);
                else
                    sPOSRet = string.Format("{0}+{1}", Convert.ToChar(nPOS / 25600), nPOS % 100);
            }
            else
            {
                if (nPOS > 256)
                    sPOSRet = string.Format("{0}{1}", Convert.ToChar(nPOS / 256), Convert.ToChar(nPOS % 256));
                else
                    sPOSRet = string.Format("{0}", Convert.ToChar(nPOS % 256));
            }
            return sPOSRet;
        }

        static WordSegment()
        {
            if (!ICTCLAS_Init("WordSegment"))
            {
                throw new Exception("Init ICTCLAS failed!");
            }
        }

        public static void ImportUserDictFile(String fileName, eCodeType codeType)
        {
            ICTCLAS_ImportUserDictFile(fileName, codeType);
            ICTCLAS_SaveTheUsrDic();
        }

        public static void Exit()
        {
            ICTCLAS_Exit();
        }
        public static List<WordSegmentResultItem> Process(string Context)
        {
            int count = Context.Length;//先得到结果的词数
            result_t[] result = new result_t[count];//在客户端申请资源
            List<WordSegmentResultItem> resultList = new List<WordSegmentResultItem>();

            //对字符串进行分词处理
            int nWrdCnt = ICTCLAS_ParagraphProcessAW(Context, result, eCodeType.CODE_TYPE_GB, 1);

            //取字符串真实长度
            byte[] mybyte = System.Text.Encoding.Default.GetBytes(Context);
            for (int i = 0; i < nWrdCnt; i++)
            {
                result_t r = result[i];
                byte[] byteWord = new byte[r.length];
                Array.Copy(mybyte, r.start, byteWord, 0, r.length);
                WordSegmentResultItem item = new WordSegmentResultItem();
                item.Type = r.word_type;
                item.Word = System.Text.Encoding.Default.GetString(byteWord);
                item.POS = GetPOSString(r.sPos);
                resultList.Add(item);
            }
            return resultList;
        }

    }

}
